package de.recipeminer.models.generic;

import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;

import java.util.Set;

public abstract class AbstractRecipe extends AnnotatableObject{
    String difficulty,instructions,title;

    long preparationTime;
    long servings;

    protected AbstractRecipe(String title, String instructions, long preparationTime,
                             String  difficulty,long servings){
  
        this.difficulty = difficulty;
        this.instructions = instructions;
        this.title = title;
        this.preparationTime = preparationTime;
        this.servings = servings;
    }

    public String description() {
        String template = "*** %s (%d) ***%n" +
                          "title: %s%n" + 
                          "ingredients: %s%n" + 
                          "instructions: %s%n";
        String ingredientListing = Joiner.on(", ").join( getIngredients());
        Splitter splitter = Splitter.on(CharMatcher.WHITESPACE).fixedLength(120);
        String splittedIngredients =  Joiner.on('\n').join(splitter.split(ingredientListing));
        Splitter trunc = Splitter.on(CharMatcher.WHITESPACE).fixedLength(240);
        String truncInstructions = trunc.split(getInstructions()).iterator().next();
        String splittedInstruction = Joiner.on('\n').join(splitter.split(truncInstructions));
        return String.format(template, getClass().getName(), getId(),
                            getTitle(), splittedIngredients, splittedInstruction);
    }

    public String getDifficulty() {
        return difficulty;
    }

    public abstract long getId();

    public abstract <IL extends AbstractIngredientLineItem>  boolean  addIngredientLineItem(IL ingredientLine);

    public abstract Set<? extends AbstractIngredientLineItem> getIngredients();
    
    public String getInstructions() {
        return instructions;
    }
    
    public long getPreparationTime() {
        return preparationTime;
    }

    public long getServings() {
        return servings;
    }

    public String getTitle() {
        return title;
    }

    @Override
    public String toString() {
        return String.format("%s #%d (%s)", getClass().getName(), getId(), getTitle());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        AbstractRecipe that = (AbstractRecipe) o;

        if (title != null ? !title.equals(that.title) : that.title != null) return false;

        return true;
    }



    @Override
    public int hashCode() {
        return title != null ? title.hashCode() : 0;
    }
}
